home *** CD-ROM | disk | FTP | other *** search
-
- #include <string.h> /* string stuff */
- #include <stdio.h> /* standard stuff */
- #include <stdlib.h> /* standard lib stuff*/
- #include <dir.h> /* directory stuff */
- #include <dos.h> /* DOS stuff */
- #include <errno.h> /* system error */
- #include <fcntl.h>
- /* #include <search.h> */
- /* #include <sys\types.h> */ /* more types!!! */
- #include <sys\stat.h> /* stat stuff... */
- /* #include <sys\utime.h> */
- #include <time.h>
- #include "makemak.h"
-
- struct ffblk dp; /* file entry in directory */
-
-
- struct dir_rec {
- char name[FNAMELEN]; /* name of the file */
- long time; /* last modified time */
- int checked; /* has it been checked? */
- } directory[MAXFILES];
-
- int count = 0, /* how many files in directory? */
- verbose = 0, /* -v (verbose) flag set... */
- dependencies = 0, /* -d (dependencies) flag set.. */
- show_times = 0, /* -s (show times) flag set */
- makefile = 1, /* if no other options, make makefile */
- srcs = 0, /* > 0 if source files are present */
- objs = 0, /* > 0 if obj files are present */
- hdrs = 0; /* > 0 if header files are present */
-
-
- #define _MAX_FNAME 13
- extern int errno; /* system error number */
- extern char defaults[][SLEN];
- extern char mak_defs[][FNAMELEN];
- static char pgm[_MAX_FNAME] = {"makemak"};
-
- char *cc_line = {"\n\t$(CC) $(C_OPTS) $(CDEFS) %s\n\n" };
- char *mc_line = {"\n\t$(MC) $(M_OPTS) $(MDEFS) %s;\n\n" };
- char *link_line = {"\t$(LINK) $(L_OPTS) $(OBJS), $(TARGET), $(LMAP), $(LIBS)\n" };
- char *link2_line = {"\t$(LINK) $(L_OPTS) @linkfile, $(TARGET), $(LMAP), $(LIBS)\n"};
-
- char compile_command[SLEN] = { "" };
-
-
- void initially_read_in_directory();
- void initialize_makefile();
- void finish_makefile();
- void get_file_modification_dates();
- void figure_out_includes(int, int);
- void makelinkfile();
- int check_for_include(char *);
- int read_directory(char *);
- int suffix(char *, char *);
- int compare(); /* must be declared w/o args for qsort */
- int dosvers();
- extern int getopt(int, char **, char *);
- extern void mak_help(char *);
-
- char *dirp;
-
-
- main(int argc, char *argv[])
- {
- extern char *getpname(char *, char *);
- extern int mak_cfg(char *);
-
- extern int optind, opterr;
- extern char *optarg;
-
- register int i;
- int c;
- int arg_err = 0;
-
- _osmajor = dosvers();
-
- if (_osmajor < 2)
- fprintf(stderr, "%s: makemak requires DOS 2.00 or later.\n", pgm);
-
- if (_osmajor >= 3)
- getpname(*argv, pgm);
-
- opterr = 0; /* supress getopt error message! */
-
- while ((c = getopt(argc, argv, "dhHsv")) != EOF)
- switch (c)
- {
- case 'd' :
- dependencies++;
- makefile = FALSE;
- break;
- case 'v' :
- verbose++;
- makefile = FALSE;
- break;
- case 's' :
- show_times++;
- makefile = FALSE;
- break;
- case 'h' :
- case 'H' :
- case '?' :
- arg_err = TRUE;
- break;
- }
-
- if (dependencies && verbose)
- {
- fprintf(stderr, "%s: Invalid option combination.\n", pgm);
- exit(4);
- }
-
- argc -= optind;
- argv += optind;
-
- if ((makefile && (argc == 0)) || arg_err)
- {
- mak_help(pgm);
- exit(3);
- }
-
- strcpy(defaults[TARGET], *argv);
-
- if (mak_cfg(pgm) != 0)
- {
- fprintf(stderr, "%s: bad dependancy configuration file.\n", pgm);
- exit(6);
- }
-
- initially_read_in_directory(); /* start up stuff */
-
- if (makefile)
- initialize_makefile();
-
- /*
- if the user wants to see the dates spin through and
- spit 'em all out!
- */
-
- if (show_times)
- {
- get_file_modification_dates(); /* read file dates */
- for (i=0; i < count; i++)
- if (suffix(".c", directory[i].name) ||
- suffix(".h", directory[i].name) ||
- suffix(".asm", directory[i].name))
- /* a legit file? */
- printf("%-15s %s", directory[i].name,
- ctime(&directory[i].time));
- }
-
- /* now let's go through and check all the source files */
-
- for (i=0; i < count; i++)
- if (suffix(".c", directory[i].name) || suffix(".asm", directory[i].name))
- figure_out_includes(i, 1); /* a source file? */
-
- if (makefile)
- finish_makefile();
-
- exit(0);
- }
-
-
- void initially_read_in_directory()
- {
- /*
- initialize the system variables and read in and sort the current directory...
- */
-
- if (findfirst(".\\*.*",&dp, 0) == 0) /* current directory */
- strcpy(directory[count++].name, strlwr(dp.ff_name));
-
- while (read_directory(directory[count++].name) && count < MAXFILES)
- ;
-
- if (count >= MAXFILES)
- {
- fprintf(stderr,
- "%s: Warning: more files than this program can deal with!\n", pgm);
- fprintf(stderr,
- "%s continuing, but it might be wrong!\n", pgm);
- }
-
- qsort((void *)directory, (size_t) --count, sizeof (directory[0]), compare);
-
- }
-
-
-
- void initialize_makefile()
- {
- /*
- outputs all the leading Makefile information as appropriate
- */
-
- /* first off, let's dump the makefile_header stuff... */
-
- register int i, len;
- FLAGS k;
- char buffer[SLEN];
- FILE *fp;
-
- printf("# Custom make file generated by %s for %s\n\n", pgm, defaults[TARGET]);
- for (k = TARGET; k <= LIBS; k++)
- printf("%s = %s\n", mak_defs[k], defaults[k]);
-
- /* next, we'll need to output "HDRS", "SRCS" and "OBJS" ... */
-
- printf("HDRS = ");
-
- for (len=8, i=0; i < count; i++)
- if (suffix(".h", directory[i].name))
- {
- ++hdrs;
- if (strlen(directory[i].name) + len > 75)
- {
- printf(" \\\n\t");
- len = 8;
- }
- printf("%s ", directory[i].name);
- len += strlen(directory[i].name)+1;
- }
-
- putchar('\n');
-
- printf("SRCS = ");
-
- for (len = 8, i=0; i < count; i++)
- if (suffix(".c", directory[i].name)
- || suffix(".asm", directory[i].name))
- {
- ++srcs;
- if (strlen(directory[i].name) + len > 75)
- {
- printf(" \\\n\t");
- len = 8;
- }
- printf("%s ", directory[i].name);
- len += strlen(directory[i].name)+1;
- }
-
- putchar('\n');
-
- if ((fp = fopen("linkfile","w")) == NULL) {
- fprintf(stderr, "Can't open linkfile\n");
- exit(1);
- }
-
- printf("OBJS = ");
-
- for (len = 8, i=0; i < count; i++)
- if (suffix(".c", directory[i].name)
- || suffix(".asm", directory[i].name))
- {
- ++objs;
- if (strlen(directory[i].name) + len > 75)
- {
- printf(" \\\n\t");
- fprintf(fp," +\n");
- len = 8;
- }
- strcpy(buffer, directory[i].name);
- strcpy(strchr(buffer, '.'), ".obj");
- /* make it a '.obj' file! */
- printf("%s ", buffer);
- fprintf(fp, "%s ", buffer);
- len += strlen(buffer)+1;
- }
-
- printf(" \n\n");
- fprintf(fp,"\n");
- fflush(fp);
- fclose(fp);
-
- }
-
-
-
- void finish_makefile()
- {
- /*
- adds some standard stuff to the end of the makefile
- */
-
- printf(compile_command);
-
- /* and the default binary target... */
-
- printf("$(TARGET):\t");
- printf("%s", (objs ? "$(OBJS) " : ""));
- printf("%s", (srcs ? "$(SRCS) " : ""));
- printf("%s", (hdrs ? "$(HDRS)\n" : "\n"));
-
- if (lengthcheck()< 50 ){
- printf("%s", link_line);
- printf("# %s", link2_line);
- }
- else {
- printf("# %s", link_line);
- printf("%s", link2_line);
- }
- }
-
-
-
- void get_file_modification_dates()
- {
- /*
- do a 'stat' on each file in this directory, saving the last
- modified date of each in the directory structure...
- */
-
- struct stat buffer;
- register int i;
-
- for (i = 0; i < count ; i++)
- if ((stat(directory[i].name, &buffer)) != 0)
- {
- fprintf(stderr,"%s: could not stat %s [%d] **\n",
- pgm, directory[i].name, errno);
- exit(errno);
- }
- else
- {
- directory[i].time = buffer.st_mtime;
- }
- }
-
-
-
- void figure_out_includes(int index, int cnt)
- {
- /*
- read the specified file, get all the files that this fellow
- includes, then change the 'time' of the file entry in the
- 'directory' structure based on the times of the files it includes.
- 'cnt' is the nesting depth that we're currently at (for verbose
- output and other I/O miscellany).
- */
-
- FILE *thefile;
- char buffer[SLEN];
- int findex, i;
-
- if (verbose)
- if (cnt == 1)
- printf("Checking file \"%s\"\n", directory[index].name);
- else
- {
- for (i=0;i<cnt;i++)
- printf(" ");
- printf("includes file \"%s\"\n", directory[index].name);
- }
-
- if (cnt == 1 && makefile)
- {
- if (strlen(compile_command) > 0)
- printf(compile_command);
- if (suffix(".c", directory[index].name))
- sprintf(compile_command, cc_line, directory[index].name);
- else if (suffix(".asm", directory[index].name))
- sprintf(compile_command, mc_line, directory[index].name);
- }
-
- if (dependencies || (makefile && cnt > 1))
- printf("%s%s ", directory[index].name, cnt == 1 ? ":" : "");
- else if (makefile && cnt == 1)
- {
- strcpy(buffer, directory[index].name);
- strcpy(strchr(buffer, '.'), ".obj");
- printf("%s:\t%s ", buffer, directory[index].name);
- }
-
- if (!verbose && !dependencies && !makefile && directory[index].checked)
- return;
-
- if ((thefile = fopen(directory[index].name,"r")) == NULL)
- {
- fprintf(stderr,"%s: could not open file %s for reading [%d] !\n",
- pgm, directory[index].name, errno);
- exit(errno);
- }
-
- /*
- okay, now let's loop through this thing and try
- to get all the #include lines...
- */
-
- while (fgets(buffer, SLEN, thefile) != NULL)
- {
- if (buffer[0] == '#') /* hmmm...a compiler directive... */
- if ((findex = check_for_include(buffer)) != -1)
- {
- figure_out_includes(findex, cnt+1);
- /* recurse... */
- }
- }
-
- directory[index].checked++;
-
- if (dependencies && cnt==1) printf("\n");
-
- (void) fclose(thefile);
- }
-
-
-
- int check_for_include(char *line)
- {
- /*
- Line is an m4 directive line - this routine figures out if it is
- an 'include' line, and if so, what file is being included. If the
- file included is contained within this directory, then this routine
- will return the index, otherwise it will return -1 if an error.
- */
-
- char *line_ptr, *word, *strtok();
- int i;
-
- line[0] = ' '; /* remove the '#' */
-
- /*
- this first section is so we can have "# include" as well
- as "#include" ... we simply get the first word token via
- calls to 'strtok()'
- */
-
- line_ptr = (char *) line; /* gets the address */
-
- if ((word = strtok(line_ptr," \t")) != NULL)
- {
- if (strcmp(word, "include") != 0)
- return(-1);
- }
- else
- return(-1);
-
- /*
- to get to here, it must be an include line and the internal strtok
- pointer must be pointing at the filename surrounded by quotes or
- '<>' characters... (note that the " in the strtok call will also
- suffice to remove the quotes from the filename too)
- */
-
- if ((word = strtok(NULL, "\t \"")) != NULL)
- {
- if (word[0] == '<')
- return(-1);
- }
- else
- return(-1);
-
- /*
- to get to here, it must have included the file that is specified
- as 'word' currently, and that file must be a specified file in
- the local directory.
- */
-
- for (i=0; i < strlen(word); i++)
- if (word[i] == '\\')
- return(-1);
-
- /*
- now, finally, we know that 'word' must be a file in the
- current directory, so we merely need to find it's index
- into the directory structure of this program and return it!
- */
-
- for (i=0; i < count; i++)
- if (strcmpi(word, directory[i].name) == 0)
- return(i);
-
- /* it wasn't in there??? */
-
- fprintf(stderr,"%s: %s not in directory.\n",
- pgm, word);
- return(-1);
- }
-
-
-
- int read_directory(char *buffer)
- {
- /*
- return the next name in the directory... returns zero when
- we're out of entries.
- */
-
- if (findnext(&dp) == 0)
- {
- strcpy(buffer, strlwr(dp.ff_name));
- return(1);
- }
-
- return(0);
- }
-
-
-
- int suffix(char *sf, char *string)
- {
- /* returns true iff the suffix of 'string' is 'sf' */
-
- register int i, j;
-
- i = strlen(string);
- j = strlen(sf);
-
- while (string[i] == sf[j] && j > 0)
- {
- i--;
- j--;
- }
-
- return(sf[0] == string[i] && j == 0);
- }
-
-
-
- int compare(struct dir_rec *a, struct dir_rec *b)
- {
- /* strcmp on name field (for sort routine) */
-
- return( strcmp(a->name, b->name));
- }
-
- int
- dosvers()
- {
- union REGS REG;
- REG.h.ah = 0x30;
- int86(0x21, ®, ®);
- return(REG.h.al);
- }
- int
- lengthcheck()
- {
- struct stat statbuf;
- int h, linklength;
-
- if ((h = open("linkfile",O_RDONLY)) == -1){
- fprintf(stderr,"Cannot open linkfile; exiting\n");
- exit(1);
- }
- if (stat("linkfile", &statbuf) == -1){
- fprintf(stderr,"Cannot stat linkfile; exiting\n");
- exit(1);
- }
- linklength = statbuf.st_size;
- close(h);
- return(linklength);
- }
-
-
-
-